package com.qingzhuge.verification.utils;

import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import com.qingzhuge.common.utils.JsonUtil;
import com.qingzhuge.common.validator.ValidatorUtil;
import com.qingzhuge.verification.dto.CloudAuthRequest;
import com.qingzhuge.verification.dto.UserAuthRequest;
import com.qingzhuge.verification.dto.UserAuthResponse;
import com.qingzhuge.verification.dto.tencent.*;
import com.qingzhuge.verification.entity.SysVerification;
import com.qingzhuge.verification.service.IIdCardAuthCloudVerification;
import com.tencentcloudapi.common.AbstractClient;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.JsonResponseModel;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Type;

@Slf4j
public class TencentcloudVerification  extends AbstractClient implements IIdCardAuthCloudVerification {
    private static String endpoint = "faceid.tencentcloudapi.com";
    private static String version = "2018-03-01";
    private static String region = "ap-chengdu";
    private static String ruleId = "0";

    /**
     * 构造client
     * @param credential 认证信息实例
     * @param region	产品地域
     * @param profile 配置实例
     */
    public TencentcloudVerification(Credential credential, String region, ClientProfile profile) {
        super(TencentcloudVerification.endpoint, TencentcloudVerification.version, credential, region, profile);
    }

    public static TencentcloudVerification of(SysVerification verification){
        Credential credential = new Credential(verification.getAccessKeyId(),verification.getAccessKeySecret());
        return new TencentcloudVerification(credential, region, new ClientProfile());
    }

    @Override
    public UserAuthResponse doAuth(CloudAuthRequest authRequest) {
        log.debug("提交申请认证:{}", authRequest);
        //RuleId=0时，使用权威证照库，RuleId为1时，需要在DetectAuth接口传入比对照片
        DetectAuthRequest req = new DetectAuthRequest();
        req.setRuleId(ruleId);
        req.setName(authRequest.getName());
        req.setIdCard(authRequest.getIdNumber());
        try {
            DetectAuthResponse authResponse = this.detectauth(req);
            String bizToken = authResponse.getBizToken();
            log.debug("authResponse RequestId:{}",authResponse.getRequestId());
            return new UserAuthResponse(bizToken, bizToken);
        } catch (TencentCloudSDKException e) {
            log.error("CloudAuth Error:{}",e);
            return new UserAuthResponse();
        }
    }

    @Override
    public UserAuthResponse getAuth(UserAuthRequest authRequest) {
        log.debug("获取认证结果:{}", authRequest);
        ValidatorUtil.validateEntity(authRequest);
        UserAuthResponse userAuthResponse = null;
        if (null != authRequest) {
            GetDetectInfoRequest req = new GetDetectInfoRequest();
            req.setBizToken(authRequest.getToken());
            req.setRuleId(ruleId);
            //指定拉取的结果信息，取值（0：全部；1：文本类；2：身份证正反面；3：视频最佳截图照片；4：视频）。
            //如 134表示拉取文本类、视频最佳截图照片、视频。
            req.setInfoType("0");
            try {
                GetDetectInfoResponse infoResponse = getDetectinfo(req);
                log.debug("infoResponse RequestId:{}", infoResponse.getRequestId());
                String info = infoResponse.getDetectInfo();
                DetectInfoStr detectInfo = gson.fromJson(info, new TypeToken<DetectInfoStr>() {
                }.getType());
                if (null != detectInfo) {
                    DetectInfo infoText = detectInfo.getText();
                    if (infoText.getStatusCode() == 0) {
                        infoText.setStatus(true);
                        authRequest.setStatus(true);
                    } else {
                        infoText.setStatus(false);
                        authRequest.setStatus(false);
                    }
                    userAuthResponse = new UserAuthResponse(authRequest.getType(),authRequest.getTicketId(),authRequest.getToken());
                    userAuthResponse.setStatus(infoText.getStatusCode() == 0);
                    infoText.setStatus(infoText.getStatusCode() == 0);
                    String json = JsonUtil.toJson(infoText);
                    userAuthResponse.setJson(json);
                }else{
                    authRequest.setStatus(false);
                }
            } catch (TencentCloudSDKException e) {
                e.printStackTrace();
            }
        }
        return userAuthResponse;
    }

    /**
     *每次开始核身前，需先调用本接口获取BizToken，用来串联核身流程，在核身完成后，用于获取验证结果信息。
     * @param req DetectAuthRequest
     * @return DetectAuthResponse
     * @throws TencentCloudSDKException
     */
    public DetectAuthResponse detectauth(DetectAuthRequest req) throws TencentCloudSDKException{
        JsonResponseModel<DetectAuthResponse> rsp;
        try {
            Type type = new TypeToken<JsonResponseModel<DetectAuthResponse>>() {
            }.getType();
            String detectAuth = this.internalRequest(req, "DetectAuth");
            rsp  = gson.fromJson(detectAuth, type);
        } catch (JsonSyntaxException e) {
            throw new TencentCloudSDKException(e.getMessage());
        }
        return rsp.response;
    }

    /**
     *完成验证后，用BizToken调用本接口获取结果信息，BizToken生成后三天内（3\*24\*3,600秒）可多次拉取。
     * @param req GetDetectInfoRequest
     * @return GetDetectInfoResponse
     * @throws TencentCloudSDKException
     */
    public GetDetectInfoResponse getDetectinfo(GetDetectInfoRequest req) throws TencentCloudSDKException{
        JsonResponseModel<GetDetectInfoResponse> rsp;
        try {
            Type type = new TypeToken<JsonResponseModel<GetDetectInfoResponse>>() {
            }.getType();
            rsp  = gson.fromJson(this.internalRequest(req, "GetDetectInfo"), type);
        } catch (JsonSyntaxException e) {
            throw new TencentCloudSDKException(e.getMessage());
        }
        return rsp.response;
    }

    /**
     *使用动作活体检测模式前，需调用本接口获取动作顺序。
     * @param req GetActionSequenceRequest
     * @return GetActionSequenceResponse
     * @throws TencentCloudSDKException
     */
    public GetActionSequenceResponse getactionsequence(GetActionSequenceRequest req) throws TencentCloudSDKException{
        JsonResponseModel<GetActionSequenceResponse> rsp;
        try {
            Type type = new TypeToken<JsonResponseModel<GetActionSequenceResponse>>() {
            }.getType();
            rsp  = gson.fromJson(this.internalRequest(req, "GetActionSequence"), type);
        } catch (JsonSyntaxException e) {
            throw new TencentCloudSDKException(e.getMessage());
        }
        return rsp.response;
    }

    /**
     *使用数字活体检测模式前，需调用本接口获取数字验证码。
     * @param req GetLiveCodeRequest
     * @return GetLiveCodeResponse
     * @throws TencentCloudSDKException
     */
    public GetLiveCodeResponse getlivecode(GetLiveCodeRequest req) throws TencentCloudSDKException{
        JsonResponseModel<GetLiveCodeResponse> rsp;
        try {
            Type type = new TypeToken<JsonResponseModel<GetLiveCodeResponse>>() {
            }.getType();
            rsp  = gson.fromJson(this.internalRequest(req, "GetLiveCode"), type);
        } catch (JsonSyntaxException e) {
            throw new TencentCloudSDKException(e.getMessage());
        }
        return rsp.response;
    }

    /**
     *传入姓名和身份证号，校验两者的真实性和一致性。
     * @param req IdCardVerificationRequest
     * @return IdCardVerificationResponse
     * @throws TencentCloudSDKException
     */
    public IdCardVerificationResponse idcardverification(IdCardVerificationRequest req) throws TencentCloudSDKException{
        JsonResponseModel<IdCardVerificationResponse> rsp;
        try {
            Type type = new TypeToken<JsonResponseModel<IdCardVerificationResponse>>() {
            }.getType();
            rsp  = gson.fromJson(this.internalRequest(req, "IdCardVerification"), type);
        } catch (JsonSyntaxException e) {
            throw new TencentCloudSDKException(e.getMessage());
        }
        return rsp.response;
    }

    /**
     *传入照片和身份信息，判断该照片与公安权威库的证件照是否属于同一个人。
     * @param req ImageRecognitionRequest
     * @return ImageRecognitionResponse
     * @throws TencentCloudSDKException
     */
    public ImageRecognitionResponse imagerecognition(ImageRecognitionRequest req) throws TencentCloudSDKException{
        JsonResponseModel<ImageRecognitionResponse> rsp;
        try {
            Type type = new TypeToken<JsonResponseModel<ImageRecognitionResponse>>() {
            }.getType();
            rsp  = gson.fromJson(this.internalRequest(req, "ImageRecognition"), type);
        } catch (JsonSyntaxException e) {
            throw new TencentCloudSDKException(e.getMessage());
        }
        return rsp.response;
    }

    /**
     *传入视频和照片，先判断视频中是否为真人，判断为真人后，再判断该视频中的人与上传照片是否属于同一个人。
     * @param req LivenessCompareRequest
     * @return LivenessCompareResponse
     * @throws TencentCloudSDKException
     */
    public LivenessCompareResponse livenesscompare(LivenessCompareRequest req) throws TencentCloudSDKException {
        JsonResponseModel<LivenessCompareResponse> rsp;
        try {
            Type type = new TypeToken<JsonResponseModel<LivenessCompareResponse>>() {
            }.getType();
            rsp  = gson.fromJson(this.internalRequest(req, "LivenessCompare"), type);
        } catch (JsonSyntaxException e) {
            throw new TencentCloudSDKException(e.getMessage());
        }
        return rsp.response;
    }

    /**
     *传入视频和身份信息，先判断视频中是否为真人，判断为真人后，再判断该视频中的人与公安权威库的证件照是否属于同一个人。
     * @param req LivenessRecognitionRequest
     * @return LivenessRecognitionResponse
     * @throws TencentCloudSDKException
     */
    public LivenessRecognitionResponse livenessrecognition(LivenessRecognitionRequest req) throws TencentCloudSDKException{
        JsonResponseModel<LivenessRecognitionResponse> rsp;
        try {
            Type type = new TypeToken<JsonResponseModel<LivenessRecognitionResponse>>() {
            }.getType();
            rsp  = gson.fromJson(this.internalRequest(req, "LivenessRecognition"), type);
        } catch (JsonSyntaxException e) {
            throw new TencentCloudSDKException(e.getMessage());
        }
        return rsp.response;
    }
}
